/*
@auther fenglei
*/
package xxdb

import (
	"context"
	"fmt"
	"github.com/bytedance/sonic"
	"github.com/redis/go-redis/v9"
	"time"
)

type RedisDao struct {
	redis *redis.Client
}

func NewRedisDao(redis *redis.Client) *RedisDao {
	return &RedisDao{redis: redis}
}

func (e *RedisDao) GetScan(key string, val interface{}) error {
	r := e.redis.Get(context.Background(), key)
	if r.Val() == "" {
		return nil
	}
	return r.Scan(&val)
}
func (e *RedisDao) Set(key string, val interface{}, expiration time.Duration) error {
	r := e.redis.Set(context.Background(), key, val, expiration)
	return r.Err()
}
func (e *RedisDao) Get(key string) (string, error) {
	return e.redis.Get(context.Background(), key).Result()
}
func (e *RedisDao) SetJson(key string, val interface{}, expiration time.Duration) error {
	valJson, err := sonic.MarshalString(val)
	if err != nil {
		return err
	}
	r := e.redis.Set(context.Background(), key, valJson, expiration)
	return r.Err()
}
func (e *RedisDao) GetJson(key string, val interface{}) error {
	r := e.redis.Get(context.Background(), key)
	if r.Val() == "" {
		return nil
	}
	b, err := r.Bytes()
	if err != nil {
		return err
	}
	return sonic.Unmarshal(b, &val)
}
func (e *RedisDao) ScanKeys(prefix string, limit int64) ([]string, error) {
	var keys []string
	cursor := uint64(0)
	for {
		var scannedKeys []string
		var err error
		scannedKeys, cursor, err = e.redis.Scan(context.Background(), cursor, fmt.Sprintf("%s*", prefix), limit).Result()
		if err != nil {
			return nil, err
		}
		keys = append(keys, scannedKeys...)
		if cursor == 0 {
			break
		}
	}
	return keys, nil
}
func (e *RedisDao) Del(key string) error {
	return e.redis.Del(context.Background(), key).Err()
}
func (e *RedisDao) Exists(keys ...string) bool {
	val, err := e.redis.Exists(context.Background(), keys...).Result()
	if err != nil {
		return false
	}
	return val > 0
}
